home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / utilitys / 410 / mapper.gfa (.txt) < prev    next >
GFA-BASIC Atari  |  1985-11-19  |  50KB  |  2,059 lines

  1. '
  2. '                              DUNGEON MAPPER
  3. '                               Version 1.0
  4. '
  5. ' In the public domain by Jeff Casbeer : GEnie J.CASBEER : CIS 76214,450
  6. '
  7. ' Unfold the general_comments procedure for program documentation.
  8. ' User documentation is in a separate file, MAPPER.DOC.
  9. ' Program requires files MAPPER.RSC and DMICONS.DAT in the same directory.
  10. '
  11. ' **** QUICK START ****
  12. '  1) Run the program.
  13. '  2) Press "Load" on the opening dialog.
  14. '  3) Load SAMPLE.MAP and SAMPLE.LEG.
  15. '  4) Right click your mouse when the load is complete.
  16. '
  17. GOSUB main_loop
  18. END
  19. > PROCEDURE general_comments              !Look here if you're hacking...
  20.   '
  21.   ' ***** IMPORTANT VARIABLES:
  22.   '
  23.   ' There are many variables, but (I hope) the significant ones are clearly
  24.   ' labelled in the <init> routine.  Here's a little more detail on the
  25.   ' really big ones.
  26.   '
  27.   ' icon$  is the screen full of icons.  They're loaded in as an SPUT sprite.
  28.   '
  29.   ' cursor$ and cursor&  cursor$ is the 10X10 grid selected as the current
  30.   '                      icon to be placed on the map with a left click.
  31.   '                      This is just an SGET of that 10X10 grid from the
  32.   '                      icon screen.
  33.   '                      Cursor& is the NUMBER of the 10X10 grid selected
  34.   '                      as the cursor$, as counted from left to right and
  35.   '                      down the "page" of icons.  i.e., the 10X10 grid
  36.   '                      in the upper-left corner of the icon page is
  37.   '                      cursor& number 0, the one next to it (right) is
  38.   '                      number 1, etc.  When the icon is placed on the
  39.   '                      map the number is placed in the map&() array.
  40.   '                      See <icon_main_loop> to see how this works.
  41.   '
  42.   ' map&() is a two dimensional array used to hold the icon number (cursor%)
  43.   '        in each "cell" (x,y) on the map.  This array is used whenever a
  44.   '        screen redraw is needed (usually by <redraw_from_array>).
  45.   '
  46.   ' legend&() holds an icon number (cursor&) for each icon defined in the
  47.   '           legend.
  48.   '
  49.   ' legend$() holds the legend text for each icon. (legend$(icon_number,
  50.   '           text_line_number)).
  51.   '
  52.   ' ***** PROGRAM FLOW:
  53.   '
  54.   ' The program initializes through <init>, then offers the icons to the user
  55.   ' first <icon_main_loop>.
  56.   '
  57.   ' The program bounces between mouse and keyboard checks in the
  58.   ' <main_loop>.  If the right button is pressed the program alternates
  59.   ' between the <icon_main_loop> and the <map_main_loop>.  These two procedures
  60.   ' offer the user the icon set and the map, respectively.
  61.   '
  62.   ' Any keypress calls <get_key>.  This routine will produce the main menu
  63.   ' <dialog_box>, unless the keypress is an arrow key.
  64.   '
  65.   ' If the key is an arrow key, the map scrolls 10 "blocks" (10X10 grids)
  66.   ' in the direction of the arrow, using the routines <scroll_east, _west,
  67.   ' _north, and _south>.  These four procedures check for map edge and call
  68.   ' <redraw_from_array> to complete the map redraw.
  69.   '
  70.   ' If the key isn't an arrow and the main menu dialog is called, <get_key>
  71.   ' calls the service routine for the menu option as appropriate:
  72.   '
  73.   ' FILE SECTION:
  74.   '
  75.   '  1) Save the map calls <save_map>.
  76.   '  2) Load the map calls <load_map>.
  77.   '  3) Save the legend calls <save_legend>.
  78.   '  4) Load the legend calls <load_legend>.
  79.   '  5) Quit calls <quit>.
  80.   '
  81.   ' EDIT SECTION:
  82.   '  6) Fill calls <fill_area>.  Fill area completes the logical fill using
  83.   '     <select_map_loc> to select the location to begin the fill and
  84.   '     uses <redraw_from_array> to redraw the screen.
  85.   '  7) Title calls <dialog_box3>.  Updates variables title$ and subtitle$.
  86.   '  8) Rotate calls <rotate_map>.  This simply saves the array and reloads
  87.   '     90 degrees offset.
  88.   '  9) Flip calls <flip_map>, which is another save/reload sequence.
  89.   ' 10) Insert Row/Column completes the logical insert with <ins_column_row>
  90.   '     and calls <redraw_from_array> to redraw the screen.
  91.   ' 11) Delete Row/Column does the same as #6 for a delete using
  92.   '     <del_column_row>.
  93.   ' 12) Edit Icons calls, strangely enough, <edit_icons>.
  94.   '
  95.   ' PRINT SECTION:
  96.   ' 13) Printer config calls <config_printer>, which gets help from dialog
  97.   '     box #6.
  98.   ' 14) Tiled calls <print_tiled>.
  99.   ' 15) Paged calls <print_paged>.  These two routines handle all printed
  100.   '     map and legend output, with the help of <print_screen>.  <print_screen>
  101.   '     calls <bottom_entry> and <top_entry>, which handle the exceptions of
  102.   '     the bottoms and tops of pages for the legend printer, and <page_eject>
  103.   '     for the obvious reason.  I would suggest that the print routines will
  104.   '     be the most difficult thing to change -- they were certainly the most
  105.   '     time consuming to write!
  106.   ' 16) Graph paper calls <print_graph_paper>.  This routine uses dialog box
  107.   '     #7.
  108.   '
  109.   ' LEGEND SECTION:
  110.   ' 17) Add/Edit Entry calls <legend_main_loop> which selects the icon to
  111.   '     be added/edited, performs the logical check of the current legend
  112.   '     entries to determine which (add or edit) is appropriate, and uses
  113.   '     <dialog_box4> to interract with the user.
  114.   ' 18) Delete Legend calls <delete_legend_entry> which selects and deletes
  115.   '     if the icon is in the legend.
  116.   ' 19) Browse Legend calls <browse_legend_entries> which uses <dialog_box5>
  117.   '     to confuse the user.
  118.   '
  119.   ' I think that's it.  Hope this helps you chop this code up enough to meet
  120.   ' your needs.  If not, drop me a line at the addresses in the author box.
  121.   ' It's usually easier (faster) to reach me on GEnie, but I get on to
  122.   ' Compuserve once or twice a month, too.
  123.   '
  124. RETURN
  125. > PROCEDURE init                          !Set up resources,arrays,etc.,etc.
  126.   ' ****************                     TEST RESOLUTION (NEEDS LOW)
  127.   CLS
  128.   IF XBIOS(4)<>0
  129.     ALERT 1," | I Need Low Resolution... | (TRUST me, it's WORTH it!) ",1," Hmmm... ",a&
  130.     END
  131.   ENDIF
  132.   ' ****************                     CONFIG PRINTER
  133.   dialog1%=4
  134.   dialog2%=XBIOS(33,dialog1%)
  135.   print_to_screen&=FALSE
  136.   ' ****************                     RESOURCES
  137.   RESERVE FRE(0)-33000
  138.   x&=RSRC_LOAD("\mapper.rsc")
  139.   IF x&=0
  140.     ALERT 1," | | Resource MAPPER.RSC Not Found ",1," Abort ",a&
  141.     GOSUB quit
  142.     END
  143.   ENDIF
  144.   ~RSRC_GADDR(0,0,dialog1%)
  145.   ~RSRC_GADDR(0,1,dialog2%)
  146.   ~RSRC_GADDR(0,2,dialog3%)
  147.   ~RSRC_GADDR(0,3,dialog4%)
  148.   ~RSRC_GADDR(0,4,dialog5%)
  149.   ~RSRC_GADDR(0,5,dialog6%)
  150.   ~RSRC_GADDR(0,6,dialog7%)
  151.   ~RSRC_GADDR(0,7,dialog8%)
  152.   ~FORM_CENTER(dialog1%,x1%,y1%,w1%,h1%)
  153.   ~FORM_CENTER(dialog2%,x2%,y2%,w2%,h2%)
  154.   ~FORM_CENTER(dialog3%,x3%,y3%,w3%,h3%)
  155.   title$="Untitled"
  156.   subtitle$="Untitled"
  157.   CHAR{{OB_SPEC(dialog3%,5)}}=title$
  158.   CHAR{{OB_SPEC(dialog3%,8)}}=subtitle$
  159.   ~FORM_CENTER(dialog4%,x4%,y4%,w4%,h4%)
  160.   ~FORM_CENTER(dialog5%,x5%,y5%,w5%,h5%)
  161.   ~FORM_CENTER(dialog6%,x6%,y6%,w6%,h6%)
  162.   ~FORM_CENTER(dialog7%,x7%,y7%,w7%,h7%)
  163.   ~OBJC_CHANGE(dialog7%,13,0,x7%,y7%,w7%,h7%,1,0)
  164.   ~FORM_CENTER(dialog8%,x8%,y8%,w8%,h8%)
  165.   ' ****************                     ICONS
  166.   IF NOT EXIST("DMICONS.DAT")
  167.     ALERT 1," | | Icon File DMICONS.DAT |       Not Found|",1," Abort ",a&
  168.     GOSUB quit
  169.     END
  170.   ENDIF
  171.   OPEN "I",#1,"DMICONS.DAT"
  172.   icons$=SPACE$(32000)
  173.   CLOSE #1
  174.   BLOAD "\DMICONS.DAT",VARPTR(icons$)
  175.   ' ****************                     INITIALIZE DUAL SCREEN LOGIC
  176.   GOSUB allocate_screens
  177.   ~XBIOS(5,L:screen%(2),L:screen%(1),-1)
  178.   CLS
  179.   SPUT icons$
  180.   ~XBIOS(5,L:screen%(1),L:screen%(1),-1)
  181.   CLS
  182.   ' ****************                     MISC INIT
  183.   SGET map$
  184.   cursor&=-1                             !Start as nothing
  185.   GOSUB blank_cursor
  186.   cursor$=blank$
  187.   ' ****************                      PRINT ROUTINE VARIABLES
  188.   DIM pr&(50,6)                          !6=lo-x,lo-y,,n,e,s,w
  189.   ARRAYFILL pr&(),-1
  190.   ' ****************                      LOGICALS
  191.   legend_saved&=TRUE                     !"Legend not saved" flag
  192.   map_saved&=TRUE                        !Logical for "Map not saved" message
  193.   ' ****************                      LET USER INPUT START ACTIVITY/SIZE
  194.   GOSUB dialog_box8
  195.   IF DIM?(map&())=0                      !Didn't load an old map...
  196.     CLS
  197.     ON ERROR GOSUB recover_init_error    !In case this won't fit in memory
  198.     ' ****************                     LEGEND VARIABLES
  199.     l_current_max&=0                      !Current # of legend entries
  200.     DIM legend$(lmax&,4)                  !Legend Text
  201.     DIM legend&(lmax&)                    !Legend Icons
  202.     DIM l&(lmax&)                         !Internal pointer array for legend&()
  203.     ARRAYFILL legend&(),-1
  204.     ARRAYFILL l&(),-1
  205.     ' ****************                      SCREEN FLAGS
  206.     on_icon&=FALSE                         !Which screen is visible...
  207.     on_map&=FALSE
  208.     ' ****************                      MAP VARIABLES
  209.     xbase&=0                               !Base values for scrolling...
  210.     ybase&=0
  211.     DIM map&(xmax&,ymax&)
  212.     DIM m|(xmax&,ymax&)         !An internal array supporting map&() operations
  213.     ARRAYFILL map&(),-1                    !-1 means the map cell is untouched.
  214.     ON ERROR
  215.   ENDIF
  216. RETURN
  217. > PROCEDURE recover_init_error            !Too big, try again...
  218.   ALERT 1," | Map/Legend Combination Won't | Fit In Memory.  Try Again... | ",1," OK ",a&
  219.   GOSUB quit
  220.   RUN
  221. RETURN
  222. > PROCEDURE dialog_box                    !Give 'em a menu...
  223.   FOR loop&=0 TO 1
  224.     x&=FORM_DIAL(loop&,0,0,0,0,0,y1%,w1%,h1%)
  225.   NEXT loop&
  226.   ~OBJC_DRAW(dialog1%,0,3,x1%,y1%,w1%,h1%)
  227.   a&=TRUE
  228.   WHILE a&=TRUE
  229.     a&=FALSE
  230.     obj%=FORM_DO(dialog1%,0)
  231.     IF obj%=33
  232.       GOSUB dialog_box2                         !Author
  233.       ~OBJC_CHANGE(dialog1%,obj%,0,x1%,y1%,w1%,h1%,0,0)
  234.       ~OBJC_DRAW(dialog1%,0,10,x1%,y1%,w1%,h1%)
  235.       a&=TRUE
  236.     ENDIF
  237.     IF obj%=14                                  !Title
  238.       GOSUB dialog_box3
  239.       ~OBJC_CHANGE(dialog1%,obj%,0,x1%,y1%,w1%,h1%,0,0)
  240.       ~OBJC_DRAW(dialog1%,0,10,x1%,y1%,w1%,h1%)
  241.       a&=TRUE
  242.     ENDIF
  243.     IF obj%=25
  244.       GOSUB config_printer                      !Printer Configuration
  245.       ~OBJC_CHANGE(dialog1%,obj%,0,x1%,y1%,w1%,h1%,0,0)
  246.       ~OBJC_DRAW(dialog1%,0,10,x1%,y1%,w1%,h1%)
  247.       a&=TRUE
  248.     ENDIF
  249.     IF obj%=24
  250.       GOSUB print_graph_paper                   !Print Graph Paper
  251.       ~OBJC_CHANGE(dialog1%,obj%,0,x1%,y1%,w1%,h1%,0,0)
  252.       ~OBJC_DRAW(dialog1%,0,10,x1%,y1%,w1%,h1%)
  253.       a&=TRUE
  254.     ENDIF
  255.   WEND
  256.   FOR pause&=1 TO 2000
  257.   NEXT pause&
  258.   ~OBJC_CHANGE(dialog1%,obj%,0,x1%,y1%,w1%,h1%,0,1)
  259.   FOR loop&=2 TO 3
  260.     x&=FORM_DIAL(loop&,0,0,0,0,x1%,y1%,w1%,h1%)
  261.   NEXT loop&
  262.   IF obj%=31                                    !Cancel
  263.     obj%=0
  264.     ~OBJC_CHANGE(dialog1%,31,0,x1%,y1%,w1%,h1%,32,0)
  265.   ENDIF
  266. RETURN
  267. > PROCEDURE dialog_box2                   !Heeeeeeere's Johnny! (author box)
  268.   FOR loop&=0 TO 1
  269.     ~FORM_DIAL(loop&,-x2%,-y2%,0,0,x2%,y2%,w2%,h2%)
  270.   NEXT loop&
  271.   ~OBJC_DRAW(dialog2%,0,10,x2%,y2%,w2%,h2%)
  272.   ~FORM_DO(dialog2%,0)
  273.   FOR pause&=1 TO 2000
  274.   NEXT pause&
  275.   ~OBJC_CHANGE(dialog2%,9,0,x2%,y2%,w2%,h2%,48,1)
  276.   FOR loop&=2 TO 3
  277.     ~FORM_DIAL(loop&,0,0,0,0,x2%,y2%,w2%,h2%)
  278.   NEXT loop&
  279. RETURN
  280. > PROCEDURE dialog_box3                   !To change the title...
  281.   FOR loop&=0 TO 1
  282.     ~FORM_DIAL(loop&,0,0,0,0,x3%,y3%,w3%,h3%)
  283.   NEXT loop&
  284.   ~OBJC_CHANGE(dialog3%,9,0,x3%,y3%,w3%,h3%,32,0)
  285.   ~OBJC_DRAW(dialog3%,0,2,x3%,y3%,w3%,h3%)
  286.   obj3%=FORM_DO(dialog3%,0)
  287.   FOR loop&=2 TO 3
  288.     ~FORM_DIAL(loop&,0,0,0,0,x3%,y3%,w3%,h3%)
  289.   NEXT loop&
  290.   title$=CHAR{{OB_SPEC(dialog3%,5)}}
  291.   subtitle$=CHAR{{OB_SPEC(dialog3%,8)}}
  292. RETURN
  293. > PROCEDURE dialog_box4                   !Legend Editor
  294.   FOR loop&=0 TO 1
  295.     ~FORM_DIAL(loop&,0,0,0,0,x4%,y4%,w4%,h4%)
  296.   NEXT loop&
  297.   ~OBJC_CHANGE(dialog4%,8,0,x4%,y4%,w4%,h4%,32,0)
  298.   ~OBJC_CHANGE(dialog4%,9,0,x4%,y4%,w4%,h4%,0,0)
  299.   ~OBJC_DRAW(dialog4%,0,2,x4%,y4%,w4%,h4%)
  300.   obj4%=FORM_DO(dialog4%,0)
  301.   FOR loop&=2 TO 3
  302.     ~FORM_DIAL(loop&,0,0,0,0,x4%,y4%,w4%,h4%)
  303.   NEXT loop&
  304. RETURN
  305. > PROCEDURE dialog_box8                   !New Map
  306.   WHILE xmax&=0
  307.     CLS
  308.     FOR loop&=0 TO 1
  309.       ~FORM_DIAL(loop&,0,0,0,0,x8%,y8%,w8%,h8%)
  310.     NEXT loop&
  311.     ~OBJC_CHANGE(dialog8%,11,0,x8%,y8%,w8%,h8%,32,0)
  312.     ~OBJC_CHANGE(dialog8%,12,0,x8%,y8%,w8%,h8%,0,0)
  313.     ~OBJC_DRAW(dialog8%,0,2,x8%,y8%,w8%,h8%)
  314.     obj8%=FORM_DO(dialog8%,0)
  315.     IF obj8%=12
  316.       FOR loop&=2 TO 3
  317.         ~FORM_DIAL(loop&,0,0,0,0,x8%,y8%,w8%,h8%)
  318.       NEXT loop&
  319.       map_saved&=TRUE
  320.       GOSUB load_map
  321.       legend_saved&=TRUE
  322.       GOSUB load_legend
  323.     ELSE
  324.       xmax&=VAL(CHAR{{OB_SPEC(dialog8%,4)}})
  325.       IF xmax&<31
  326.         xmax&=31
  327.       ENDIF
  328.       ymax&=xmax&
  329.       lmax&=VAL(CHAR{{OB_SPEC(dialog8%,8)}})    !Maximum # of legend entries
  330.       FOR loop&=2 TO 3
  331.         ~FORM_DIAL(loop&,0,0,0,0,x8%,y8%,w8%,h8%)
  332.       NEXT loop&
  333.     ENDIF
  334.   WEND
  335. RETURN
  336. > PROCEDURE main_loop                     !Bounce between mouse and keyboard
  337.   GOSUB init
  338.   GOSUB icon_main_loop
  339.   forever&=TRUE
  340.   WHILE forever&
  341.     kbd$=INKEY$
  342.     MOUSE mx&,my&,mse&
  343.     IF mse&>0 AND NOT (mse&=1 AND on_map&)
  344.       WHILE MOUSEK>0
  345.       WEND
  346.     ENDIF
  347.     IF kbd$<>""
  348.       GOSUB get_key
  349.     ELSE IF mse&=2 AND on_icon&
  350.       GOSUB map_main_loop
  351.     ELSE IF mse&=2 AND on_map&
  352.       GOSUB icon_main_loop
  353.     ELSE IF mse&=1 AND on_map&
  354.       GOSUB map_main_loop
  355.     ELSE IF mse&=1 AND on_icon&
  356.       GOSUB icon_main_loop
  357.     ENDIF
  358.   WEND
  359. RETURN
  360. > PROCEDURE icon_main_loop                !Go get another icon
  361.   IF NOT on_icon&
  362.     SGET map$
  363.     CLS
  364.     SPUT icons$
  365.     on_icon&=TRUE
  366.     on_map&=FALSE
  367.   ENDIF
  368.   IF mse&=1
  369.     x&=INT(mx&/10)*10                   !This is the cursor% decode logic
  370.     y&=INT(my&/10)*10
  371.     GET x&,y&,x&+9,y&+9,cursor$         !Pick up the cursor$
  372.     PUT x&,y&,cursor$,10                !Invert it and put it back down.
  373.     FOR i&=1 TO 1000                    !Pause a sec...
  374.     NEXT i&
  375.     PUT x&,y&,cursor$                   !...And put it back down right.
  376.     IF cursor$<>blank$
  377.       cursor&=(x&/10)+(y&/10)*32          !Important variable!
  378.     ELSE
  379.       cursor&=-1
  380.     ENDIF
  381.   ENDIF
  382. RETURN
  383. > PROCEDURE map_main_loop                 !Draw on the map
  384.   IF NOT on_map&
  385.     CLS
  386.     SPUT map$
  387.     on_icon&=FALSE
  388.     on_map&=TRUE
  389.   ENDIF
  390.   IF mse&=1
  391.     x&=INT(mx&/10)*10
  392.     y&=INT(my&/10)*10
  393.     PUT x&,y&,cursor$
  394.     map&(INT(mx&/10)+xbase&,INT(my&/10)+ybase&)=cursor&
  395.     map_saved&=FALSE
  396.   ENDIF
  397. RETURN
  398. > PROCEDURE get_key                       !Keyboard central
  399.   IF LEN(kbd$)=1
  400.     IF on_map&
  401.       SGET map$
  402.     ENDIF
  403.     GOSUB dialog_box
  404.     IF on_icon&
  405.       CLS
  406.       SPUT icons$
  407.     ELSE
  408.       CLS
  409.       SPUT map$
  410.     ENDIF
  411.     IF obj%>0
  412.       SELECT obj%
  413.       CASE 4
  414.         GOSUB save_map
  415.       CASE 5
  416.         GOSUB load_map
  417.       CASE 6
  418.         a&=1
  419.         IF NOT legend_saved&
  420.           ALERT 2," | This LEGEND Is NOT Saved. | Quit Without Saving It? | ",2,"Yes|No",a&
  421.         ENDIF
  422.         IF map_saved&
  423.           IF a&=1
  424.             GOSUB quit
  425.           ENDIF
  426.         ELSE
  427.           IF a&=1
  428.             ALERT 2," | This MAP Is NOT Saved. | Quit Without Saving It? | ",2,"Yes|No",a&
  429.             IF a&=1
  430.               GOSUB quit
  431.             ENDIF
  432.           ENDIF
  433.         ENDIF
  434.       CASE 8
  435.         GOSUB load_legend
  436.       CASE 9
  437.         GOSUB save_legend
  438.       CASE 13
  439.         GOSUB fill_area
  440.       CASE 15
  441.         GOSUB ins_column_row
  442.       CASE 17
  443.         GOSUB del_column_row
  444.       CASE 18
  445.         GOSUB rotate_map
  446.       CASE 19
  447.         GOSUB flip_map
  448.       CASE 20
  449.         GOSUB edit_icons
  450.       CASE 21
  451.         GOSUB print_paged
  452.       CASE 22
  453.         GOSUB print_paged
  454.       CASE 23
  455.         GOSUB print_tiled
  456.       CASE 28
  457.         GOSUB legend_main_loop
  458.       CASE 29
  459.         GOSUB delete_legend_entry
  460.       CASE 30
  461.         GOSUB browse_legend_entries
  462.       ENDSELECT
  463.     ENDIF
  464.   ELSE
  465.     SELECT CVI(kbd$)
  466.     CASE 72
  467.       GOSUB scroll_north
  468.     CASE 80
  469.       GOSUB scroll_south
  470.     CASE 75
  471.       GOSUB scroll_west
  472.     CASE 77
  473.       GOSUB scroll_east
  474.     ENDSELECT
  475.   ENDIF
  476. RETURN
  477. > PROCEDURE legend_main_loop              !Add/Edit legend entries.
  478.   IF l_current_max&<lmax&
  479.     WHILE MOUSEK>0
  480.     WEND
  481.     cursor2$=cursor$
  482.     cursor2&=cursor&
  483.     ALERT 2," | Select The Subject Icon. | Right Click When Done. ",1," OK | Cursor | Cancel ",a&
  484.     IF a&<3
  485.       IF a&=1
  486.         MOUSE mx&,my&,mse&
  487.         WHILE mse&<>2
  488.           MOUSE mx&,my&,mse&
  489.           GOSUB icon_main_loop
  490.         WEND
  491.       ENDIF
  492.       IF cursor$<>blank$
  493.         CLS
  494.         PRINT AT(5,2);"Legend entry for icon..."
  495.         PUT 23*10,8,cursor$
  496.         j&=-1
  497.         FOR i&=0 TO l_current_max&
  498.           IF legend&(i&)=cursor&
  499.             j&=i&
  500.           ENDIF
  501.         NEXT i&
  502.         IF j&>=0
  503.           CHAR{{OB_SPEC(dialog4%,3)}}=legend$(j&,0)
  504.           CHAR{{OB_SPEC(dialog4%,4)}}=legend$(j&,1)
  505.           CHAR{{OB_SPEC(dialog4%,5)}}=legend$(j&,2)
  506.           CHAR{{OB_SPEC(dialog4%,6)}}=legend$(j&,3)
  507.           CHAR{{OB_SPEC(dialog4%,7)}}=legend$(j&,4)
  508.           GOSUB dialog_box4
  509.           IF obj4%=8
  510.             legend$(j&,0)=CHAR{{OB_SPEC(dialog4%,3)}}
  511.             legend$(j&,1)=CHAR{{OB_SPEC(dialog4%,4)}}
  512.             legend$(j&,2)=CHAR{{OB_SPEC(dialog4%,5)}}
  513.             legend$(j&,3)=CHAR{{OB_SPEC(dialog4%,6)}}
  514.             legend$(j&,4)=CHAR{{OB_SPEC(dialog4%,7)}}
  515.             legend_saved&=FALSE
  516.           ENDIF
  517.         ELSE
  518.           CHAR{{OB_SPEC(dialog4%,3)}}=""
  519.           CHAR{{OB_SPEC(dialog4%,4)}}=""
  520.           CHAR{{OB_SPEC(dialog4%,5)}}=""
  521.           CHAR{{OB_SPEC(dialog4%,6)}}=""
  522.           CHAR{{OB_SPEC(dialog4%,7)}}=""
  523.           GOSUB dialog_box4
  524.           IF obj4%=8
  525.             legend$(l_current_max&,0)=CHAR{{OB_SPEC(dialog4%,3)}}
  526.             legend$(l_current_max&,1)=CHAR{{OB_SPEC(dialog4%,4)}}
  527.             legend$(l_current_max&,2)=CHAR{{OB_SPEC(dialog4%,5)}}
  528.             legend$(l_current_max&,3)=CHAR{{OB_SPEC(dialog4%,6)}}
  529.             legend$(l_current_max&,4)=CHAR{{OB_SPEC(dialog4%,7)}}
  530.             legend&(l_current_max&)=cursor&
  531.             legend_saved&=FALSE
  532.             INC l_current_max&
  533.           ENDIF
  534.         ENDIF
  535.       ELSE
  536.         ALERT 1," | Can't Legend A Blank Cursor | ",1," OK ",a&
  537.       ENDIF
  538.     ENDIF
  539.     cursor$=cursor2$
  540.     cursor&=cursor2&
  541.     CLS
  542.     GOSUB recover_screen
  543.   ELSE
  544.     ALERT 1," | Out Of Legend Space | ",1," OK ",a&
  545.   ENDIF
  546. RETURN
  547. > PROCEDURE delete_legend_entry           !Don't need it?  Lose it here.
  548.   ALERT 3," | Select The Subject Icon. | Right Click When Done. ",1," OK | Cancel ",a&
  549.   IF a&=1
  550.     MOUSE mx&,my&,mse&
  551.     WHILE mse&<>2
  552.       MOUSE mx&,my&,mse&
  553.       GOSUB icon_main_loop
  554.     WEND
  555.     j&=-1
  556.     FOR i&=0 TO l_current_max&
  557.       IF legend&(i&)=cursor&
  558.         j&=i&
  559.       ENDIF
  560.     NEXT i&
  561.     IF j&>=0
  562.       FOR i&=j& TO l_current_max&
  563.         legend&(i&)=legend&(i&+1)
  564.         legend$(i&,0)=legend$(i&+1,0)
  565.         legend$(i&,1)=legend$(i&+1,1)
  566.         legend$(i&,2)=legend$(i&+1,2)
  567.         legend$(i&,3)=legend$(i&+1,3)
  568.         legend$(i&,4)=legend$(i&+1,4)
  569.       NEXT i&
  570.       DEC l_current_max&
  571.       ALERT 1," | Icon Found And Deleted | From Legend | ",1," OK ",a&
  572.       IF l_current_max&=0
  573.         legend_saved&=TRUE
  574.       ENDIF
  575.     ELSE
  576.       ALERT 3," | Icon Not Found In Legend |  ",1," OK ",a&
  577.     ENDIF
  578.   ENDIF
  579. RETURN
  580. > PROCEDURE browse_legend_entries         !Includes dialog box #5.
  581.   IF l_current_max&>0
  582.     legend_saved&=FALSE
  583.     j&=0
  584.     FOR loop&=0 TO 1
  585.       ~FORM_DIAL(loop&,0,0,0,0,x5%,y5%,w5%,h5%)
  586.     NEXT loop&
  587.     WHILE j&<l_current_max& AND l_current_max&>0
  588.       x&=legend&(j&)
  589.       cursory&=INT(x&/32)*10
  590.       cursorx&=MOD(x&,32)*10
  591.       CLS
  592.       SPUT icons$
  593.       GET cursorx&,cursory&,cursorx&+9,cursory&+9,cursor2$
  594.       CLS
  595.       PRINT AT(5,2);"Legend entry for icon..."
  596.       PUT 23*10,8,cursor2$
  597.       CHAR{{OB_SPEC(dialog5%,4)}}=legend$(j&,0)
  598.       CHAR{{OB_SPEC(dialog5%,5)}}=legend$(j&,1)
  599.       CHAR{{OB_SPEC(dialog5%,6)}}=legend$(j&,2)
  600.       CHAR{{OB_SPEC(dialog5%,7)}}=legend$(j&,3)
  601.       CHAR{{OB_SPEC(dialog5%,8)}}=legend$(j&,4)
  602.       ~OBJC_CHANGE(dialog5%,9,0,x5%,y5%,w5%,h5%,32,0)
  603.       ~OBJC_DRAW(dialog5%,0,2,x5%,y5%,w5%,h5%)
  604.       obj5%=FORM_DO(dialog5%,0)
  605.       ~OBJC_CHANGE(dialog5%,obj5%,0,x5%,y5%,w5%,h5%,0,0)
  606.       SELECT obj5%
  607.       CASE 10                                           !Quit
  608.         j&=l_current_max&+1
  609.       CASE 9                                            !Next
  610.         legend$(j&,0)=CHAR{{OB_SPEC(dialog5%,4)}}
  611.         legend$(j&,1)=CHAR{{OB_SPEC(dialog5%,5)}}
  612.         legend$(j&,2)=CHAR{{OB_SPEC(dialog5%,6)}}
  613.         legend$(j&,3)=CHAR{{OB_SPEC(dialog5%,7)}}
  614.         legend$(j&,4)=CHAR{{OB_SPEC(dialog5%,8)}}
  615.         INC j&
  616.         IF j&=l_current_max&
  617.           ALERT 3," | End Of Legend | ",1," OK ",a&
  618.         ENDIF
  619.       CASE 11                                           !Previous
  620.         legend$(j&,0)=CHAR{{OB_SPEC(dialog5%,4)}}
  621.         legend$(j&,1)=CHAR{{OB_SPEC(dialog5%,5)}}
  622.         legend$(j&,2)=CHAR{{OB_SPEC(dialog5%,6)}}
  623.         legend$(j&,3)=CHAR{{OB_SPEC(dialog5%,7)}}
  624.         legend$(j&,4)=CHAR{{OB_SPEC(dialog5%,8)}}
  625.         DEC j&
  626.       CASE 3                                            !Delete
  627.         FOR i&=j& TO l_current_max&
  628.           legend&(i&)=legend&(i&+1)
  629.           legend$(i&,0)=legend$(i&+1,0)
  630.           legend$(i&,1)=legend$(i&+1,1)
  631.           legend$(i&,2)=legend$(i&+1,2)
  632.           legend$(i&,3)=legend$(i&+1,3)
  633.           legend$(i&,4)=legend$(i&+1,4)
  634.         NEXT i&
  635.         DEC l_current_max&
  636.         ALERT 1," | Icon Found And Deleted | From Legend | ",1," OK ",a&
  637.         IF l_current_max&=0
  638.           legend_saved&=TRUE
  639.           ALERT 3," | No More Legend Entries Exist | ",1," OK ",a&
  640.         ENDIF
  641.         IF j&>=l_current_max& AND l_current_max&>0
  642.           DEC j&
  643.         ENDIF
  644.       ENDSELECT
  645.       IF j&=-1
  646.         j&=0
  647.         ALERT 3," | Beginning Of Legend | ",1," OK ",a&
  648.       ENDIF
  649.     WEND
  650.     FOR loop&=2 TO 3
  651.       ~FORM_DIAL(loop&,0,0,0,0,x5%,y5%,w5%,h5%)
  652.     NEXT loop&
  653.     GOSUB recover_screen
  654.   ELSE
  655.     ALERT 3," | No Legend Entries Exist | ",1," OK ",a&
  656.   ENDIF
  657. RETURN
  658. > PROCEDURE recover_screen                !Reset from non-map/icon screen
  659.   IF on_icon&
  660.     CLS
  661.     SPUT icons$
  662.   ELSE
  663.     CLS
  664.     SPUT map$
  665.   ENDIF
  666.   SHOWM
  667. RETURN
  668. > PROCEDURE scroll_east                   !The...
  669.   IF on_map&
  670.     IF xbase&+41<xmax&
  671.       xbase&=xbase&+10
  672.       GOSUB redraw_from_array
  673.     ELSE IF xbase&+31=xmax&
  674.       ALERT 3," | End Of Map East... | ",1,"OK",a&
  675.     ELSE
  676.       xbase&=xmax&-31
  677.       GOSUB redraw_from_array
  678.     ENDIF
  679.   ENDIF
  680. RETURN
  681. > PROCEDURE scroll_west                   !Four...
  682.   IF on_map&
  683.     IF xbase&-10>=0
  684.       xbase&=xbase&-10
  685.       GOSUB redraw_from_array
  686.     ELSE IF xbase&=0
  687.       ALERT 3," | End Of Map West... | ",1,"OK",a&
  688.     ELSE
  689.       xbase&=0
  690.       GOSUB redraw_from_array
  691.     ENDIF
  692.   ENDIF
  693. RETURN
  694. > PROCEDURE scroll_north                  !Scroll...
  695.   IF on_map&
  696.     IF ybase&-10>=0
  697.       ybase&=ybase&-10
  698.       GOSUB redraw_from_array
  699.     ELSE IF ybase&=0
  700.       ALERT 3," | End Of Map North... | ",1,"OK",a&
  701.     ELSE
  702.       ybase&=0
  703.       GOSUB redraw_from_array
  704.     ENDIF
  705.   ENDIF
  706. RETURN
  707. > PROCEDURE scroll_south                  !Directions
  708.   IF on_map&
  709.     IF ybase&+29<ymax&
  710.       ybase&=ybase&+10
  711.       GOSUB redraw_from_array
  712.     ELSE IF ybase&+19=ymax&
  713.       ALERT 3," | End Of Map South... | ",1,"OK",a&
  714.     ELSE
  715.       ybase&=ymax&-19
  716.       GOSUB redraw_from_array
  717.     ENDIF
  718.   ENDIF
  719. RETURN
  720. > PROCEDURE redraw_from_array             !Redraw after scroll, load, etc.
  721.   LOCAL x&,i&,j&,cursor$
  722.   x&=-1
  723.   CLS
  724.   FOR i&=xbase& TO xbase&+31
  725.     FOR j&=ybase& TO ybase&+19
  726.       IF map&(i&,j&)>=0
  727.         IF map&(i&,j&)<>x&
  728.           cursory&=INT(map&(i&,j&)/32)*10
  729.           cursorx&=MOD(map&(i&,j&),32)*10
  730.           ~XBIOS(5,L:screen%(2),L:screen%(1),-1)  !Peek at the icon screen
  731.           GET cursorx&,cursory&,cursorx&+9,cursory&+9,cursor$  !Get an icon
  732.           ~XBIOS(5,L:screen%(1),L:screen%(1),-1)  !Back to the map
  733.         ENDIF
  734.         PUT (i&-xbase&)*10,(j&-ybase&)*10,cursor$
  735.         x&=map&(i&,j&)
  736.       ENDIF
  737.     NEXT j&
  738.   NEXT i&
  739.   SHOWM
  740. RETURN
  741. > PROCEDURE select_map_loc                !Chooses any visible map location
  742.   IF NOT on_map&
  743.     CLS
  744.     SPUT map$
  745.     on_icon&=FALSE
  746.     on_map&=TRUE
  747.   ENDIF
  748.   DEFMOUSE 7
  749.   WHILE MOUSEK>0
  750.   WEND
  751.   MOUSE mx&,my&,mse&
  752.   i&=0
  753.   WHILE mse&=0
  754.     INC i&
  755.     IF i&=100
  756.       i&=0
  757.       IF j&=1
  758.         j&=0
  759.         DEFMOUSE 6
  760.       ELSE
  761.         j&=1
  762.         DEFMOUSE 7
  763.       ENDIF
  764.     ENDIF
  765.     MOUSE mx&,my&,mse&
  766.   WEND
  767.   DEFMOUSE 0
  768.   x&=INT(mx&/10)
  769.   y&=INT(my&/10)
  770. RETURN
  771. > PROCEDURE save_map                      !Save Map to disk
  772.   CLS
  773.   PRINT "Save Map..."
  774.   mapfilename$=""
  775.   FILESELECT "\*.MAP","",mapfilename$
  776.   IF mapfilename$>"" AND RIGHT$(mapfilename$,1)<>"\"
  777.     IF INSTR(mapfilename$,".")
  778.       mapfilename$=LEFT$(mapfilename$,INSTR(mapfilename$,".")-1)
  779.     ENDIF
  780.     mapfilename$=mapfilename$+".MAP"
  781.     ON ERROR GOSUB save_map_error
  782.     OPEN "O",#1,mapfilename$
  783.     CLS
  784.     PRINT "Saving Map... ";mapfilename$
  785.     DEFMOUSE 2
  786.     WRITE #1,title$
  787.     WRITE #1,subtitle$
  788.     WRITE #1,xmax&
  789.     WRITE #1,ymax&
  790.     FOR i&=0 TO xmax&
  791.       FOR j&=0 TO ymax&
  792.         WRITE #1,map&(i&,j&)
  793.       NEXT j&
  794.       PRINT AT(1,2);USING "##.#% Complete.",(i&/xmax&)*100
  795.     NEXT i&
  796.     CLOSE #1
  797.     ON ERROR
  798.     DEFMOUSE 0
  799.     map_saved&=TRUE
  800.   ELSE
  801.     ALERT 1," | Map Is NOT Saved... | ",1,"OK",a&
  802.   ENDIF
  803.   GOSUB recover_screen
  804. RETURN
  805. > PROCEDURE save_map_error                !Recover from disk error if possible
  806.   ALERT 2," | Error Encountered During Save | "+ERR$(ERR),1," OK ",a&
  807.   RESUME map_save_err_return
  808. map_save_err_return:
  809.   CLOSE #1
  810.   DEFMOUSE 0
  811.   ALERT 1," | Map Saved State Is Unknown. | ",1,"OK",a&
  812.   GOSUB recover_screen
  813. RETURN
  814. > PROCEDURE save_legend                   !Save Legend to disk
  815.   CLS
  816.   PRINT "Save Legend..."
  817.   mapfilename$=""
  818.   FILESELECT "\*.LEG","",mapfilename$
  819.   IF mapfilename$>"" AND RIGHT$(mapfilename$,1)<>"\"
  820.     IF INSTR(mapfilename$,".")
  821.       mapfilename$=LEFT$(mapfilename$,INSTR(mapfilename$,".")-1)
  822.     ENDIF
  823.     mapfilename$=mapfilename$+".LEG"
  824.     ON ERROR GOSUB save_legend_error
  825.     OPEN "O",#1,mapfilename$
  826.     CLS
  827.     PRINT "Saving Legend... ";mapfilename$
  828.     DEFMOUSE 2
  829.     WRITE #1,lmax&
  830.     WRITE #1,l_current_max&
  831.     FOR i&=0 TO lmax&
  832.       WRITE #1,legend&(i&)
  833.       PRINT AT(1,2);USING "PART 1 of 2: ##.#% Complete.",(i&/lmax&)*100
  834.     NEXT i&
  835.     FOR i&=0 TO l_current_max&
  836.       FOR j&=0 TO 4
  837.         WRITE #1,legend$(i&,j&)
  838.       NEXT j&
  839.       IF l_current_max&>10
  840.         PRINT AT(1,2);USING "PART 2 of 2: ##.#% Complete.",(i&/l_current_max&)*100
  841.       ELSE
  842.         PRINT AT(1,2);"PART 2 of 2: Saving..."
  843.       ENDIF
  844.     NEXT i&
  845.     CLOSE #1
  846.     ON ERROR
  847.     DEFMOUSE 0
  848.     legend_saved&=TRUE
  849.   ELSE
  850.     ALERT 1," | Legend Is NOT Saved... | ",1,"OK",a&
  851.   ENDIF
  852.   GOSUB recover_screen
  853. RETURN
  854. > PROCEDURE save_legend_error             !Recover from disk error if possible
  855.   ALERT 2," | Error Encountered During Save | "+ERR$(ERR),1," OK ",a&
  856.   RESUME legend_save_err_return
  857. legend_save_err_return:
  858.   CLOSE #1
  859.   DEFMOUSE 0
  860.   ALERT 1," | Legend Saved State Is Unknown. | ",1,"OK",a&
  861.   GOSUB recover_screen
  862. RETURN
  863. > PROCEDURE load_map                      !Load Map from disk
  864.   LOCAL i&,j&
  865.   IF NOT map_saved&
  866.     ALERT 2," | This Map Isn't Saved. | Load Another Map Anyway? ",2," Yes | No ",a&
  867.   ELSE
  868.     a&=1
  869.   ENDIF
  870.   IF a&=1
  871.     CLS
  872.     PRINT "Load Map..."
  873.     mapfilename$=""
  874.     FILESELECT "\*.MAP","",mapfilename$
  875.     IF mapfilename$>"" AND RIGHT$(mapfilename$,1)<>"\"
  876.       IF RIGHT$(mapfilename$,1)="."
  877.         mapfilename$=LEFT$(mapfilename$,INSTR(mapfilename$,".")-1)
  878.       ENDIF
  879.       ON ERROR GOSUB load_map_error
  880.       OPEN "I",#1,mapfilename$
  881.       CLS
  882.       PRINT "Loading Map... ";mapfilename$
  883.       DEFMOUSE 2
  884.       on_icon&=FALSE
  885.       on_map&=FALSE
  886.       xbase&=0                      !See init for explanation...
  887.       ybase&=0
  888.       INPUT #1,title$
  889.       INPUT #1,subtitle$
  890.       CHAR{{OB_SPEC(dialog3%,5)}}=title$
  891.       CHAR{{OB_SPEC(dialog3%,8)}}=subtitle$
  892.       INPUT #1,xmax&
  893.       INPUT #1,ymax&
  894.       ERASE map&(),m|()
  895.       DIM map&(xmax&,ymax&)
  896.       DIM m|(xmax&,ymax&)
  897.       ARRAYFILL map&(),-1
  898.       FOR i&=0 TO xmax&
  899.         FOR j&=0 TO ymax&
  900.           INPUT #1,map&(i&,j&)
  901.         NEXT j&
  902.         PRINT AT(1,2);USING "##.#% Complete.",(i&/xmax&)*100
  903.       NEXT i&
  904.       CLOSE #1
  905.       ~XBIOS(5,L:screen%(2),L:screen%(1),-1)
  906.       CLS
  907.       SPUT icons$
  908.       ~XBIOS(5,L:screen%(1),L:screen%(1),-1)
  909.       CLS
  910.       ON ERROR
  911.       DEFMOUSE 0
  912.       GOSUB redraw_from_array
  913.       GOSUB icon_main_loop
  914.       map_saved&=TRUE
  915.     ELSE
  916.       ALERT 1," | Map Is NOT Loaded... | ",1,"OK",a&
  917.       IF xmax&>0
  918.         GOSUB recover_screen
  919.       ENDIF
  920.     ENDIF
  921.   ENDIF
  922. RETURN
  923. > PROCEDURE load_legend                   !Load Legend from disk
  924.   LOCAL i&,j&
  925.   IF (NOT legend_saved&) AND l_current_max&>0
  926.     ALERT 2," | This Legend Isn't Saved. | Load Another One Anyway? ",2," Yes | No ",a&
  927.   ELSE
  928.     a&=1
  929.   ENDIF
  930.   IF a&=1
  931.     CLS
  932.     PRINT "Load Legend..."
  933.     mapfilename$=""
  934.     FILESELECT "\*.LEG","",mapfilename$
  935.     IF mapfilename$>"" AND RIGHT$(mapfilename$,1)<>"\"
  936.       IF RIGHT$(mapfilename$,1)="."
  937.         mapfilename$=LEFT$(mapfilename$,INSTR(mapfilename$,".")-1)
  938.       ENDIF
  939.       ON ERROR GOSUB load_legend_error
  940.       OPEN "I",#1,mapfilename$
  941.       CLS
  942.       PRINT "Loading Legend... ";mapfilename$
  943.       DEFMOUSE 2
  944.       ERASE legend$(),l&(),legend&()
  945.       INPUT #1,lmax&
  946.       DIM legend$(lmax&,4)
  947.       DIM legend&(lmax&)                    !Legend Icons
  948.       DIM l&(lmax&)                         !Internal flag array for legend&()
  949.       INPUT #1,l_current_max&
  950.       FOR i&=0 TO lmax&
  951.         INPUT #1,legend&(i&)
  952.         IF lmax&>0 AND MOD(i&,10)=0
  953.           PRINT AT(1,2);USING "PART 1 of 2: ##.#% Complete.",(i&/lmax&)*100
  954.         ENDIF
  955.       NEXT i&
  956.       PRINT AT(1,2);"                                                      "
  957.       FOR i&=0 TO l_current_max&
  958.         FOR j&=0 TO 4
  959.           INPUT #1,legend$(i&,j&)
  960.         NEXT j&
  961.         IF l_current_max&>10
  962.           PRINT AT(1,2);USING "PART 2 of 2: ##.#% Complete.",(i&/l_current_max&)*100
  963.         ELSE
  964.           PRINT AT(1,2);"PART 2 of 2: Loading..."
  965.         ENDIF
  966.       NEXT i&
  967.       CLOSE #1
  968.       ON ERROR
  969.       DEFMOUSE 0
  970.       legend_saved&=TRUE
  971.       GOSUB redraw_from_array
  972.     ELSE
  973.       ALERT 1," | Legend Is NOT Loaded... | ",1,"OK",a&
  974.     ENDIF
  975.     GOSUB recover_screen
  976.   ENDIF
  977. RETURN
  978. > PROCEDURE load_map_error                !Recover from mem error if possible
  979.   ERASE map&(),m|()
  980.   ALERT 2," | Error Encountered During Load | ",1,"Show Me",a&
  981.   ~FORM_ALERT(1,ERR$(ERR))
  982.   CLOSE #1
  983.   DEFMOUSE 0
  984.   ALERT 2," | No Map Loaded.| Program Restarting. | ",1,"Shoot",a&
  985.   GOSUB quit
  986.   RUN
  987. RETURN
  988. > PROCEDURE load_legend_error                !Recover from mem error if possible
  989.   ERASE legend$(),legend&(),l&()
  990.   ALERT 2," | Error Encountered During Load | ",1,"Show Me",a&
  991.   ~FORM_ALERT(1,ERR$(ERR))
  992.   CLOSE #1
  993.   DEFMOUSE 0
  994.   ALERT 3," | No Legend Loaded.| ",1,"Enough!",a&
  995.   l_current_max&=0
  996.   lmax&=0
  997.   DIM legend$(lmax&,4)                  !Legend Text
  998.   DIM legend&(lmax&)                    !Legend Icons
  999.   DIM l&(lmax&)                         !Internal pointer array for legend&()
  1000.   RESUME x
  1001. x:
  1002.   GOSUB recover_screen
  1003. RETURN
  1004. > PROCEDURE rotate_map                    !Turn it clockwise
  1005.   IF ymax&<>xmax&
  1006.     ALERT 3," | Can't Rotate A Map | That Isn't Square |",1," OK ",a&
  1007.   ELSE
  1008.     ALERT 2," | VERIFY: You Wish To | Rotate This Map? | (Disk Space Needed! SAVE!)",1," Yes | Cancel ",a&
  1009.     IF a&=1
  1010.       IF NOT EXIST("iomap.map")
  1011.         ON ERROR GOSUB iomap_error
  1012.         OPEN "O",#1,"iomap.map"
  1013.         DEFMOUSE 2
  1014.         FOR i&=0 TO xmax&
  1015.           FOR j&=0 TO ymax&
  1016.             WRITE #1,map&(i&,j&)
  1017.           NEXT j&
  1018.         NEXT i&
  1019.         CLOSE #1
  1020.         OPEN "i",#1,"iomap.map"
  1021.         FOR i&=0 TO xmax&
  1022.           FOR j&=ymax& TO 0 STEP -1
  1023.             INPUT #1,map&(j&,i&)
  1024.           NEXT j&
  1025.         NEXT i&
  1026.         CLOSE #1
  1027.         KILL "iomap.map"
  1028.         ON ERROR
  1029.         GOSUB redraw_from_array
  1030.         DEFMOUSE 0
  1031.       ELSE
  1032.         ALERT 1," | I Use The File Name | 'IOMAP.MAP' To Rotate. | Please Rename Your File. |",1," OK ",a&
  1033.       ENDIF
  1034.     ENDIF
  1035.   ENDIF
  1036. RETURN
  1037. > PROCEDURE flip_map                      !Switch east-west
  1038.   IF ymax&<>xmax&
  1039.     ALERT 3," | Can't Flip A Map | That Isn't Square |",1," OK ",a&
  1040.   ELSE
  1041.     ALERT 2," | VERIFY: You Wish To | Flip This Map? | (Disk Space Needed! SAVE!)",1," Yes | Cancel ",a&
  1042.     IF a&=1
  1043.       IF NOT EXIST("iomap.map")
  1044.         ON ERROR GOSUB iomap_error
  1045.         OPEN "O",#1,"iomap.map"
  1046.         DEFMOUSE 2
  1047.         FOR i&=0 TO xmax&
  1048.           FOR j&=0 TO ymax&
  1049.             WRITE #1,map&(i&,j&)
  1050.           NEXT j&
  1051.         NEXT i&
  1052.         CLOSE #1
  1053.         OPEN "i",#1,"iomap.map"
  1054.         FOR i&=xmax& TO 0 STEP -1
  1055.           FOR j&=0 TO ymax&
  1056.             INPUT #1,map&(i&,j&)
  1057.           NEXT j&
  1058.         NEXT i&
  1059.         CLOSE #1
  1060.         KILL "iomap.map"
  1061.         ON ERROR
  1062.         GOSUB redraw_from_array
  1063.         DEFMOUSE 0
  1064.       ELSE
  1065.         ALERT 1," | I Use The File Name | 'IOMAP.MAP' To Flip. | Please Rename Your File. |",1," OK ",a&
  1066.       ENDIF
  1067.     ENDIF
  1068.   ENDIF
  1069. RETURN
  1070. > PROCEDURE iomap_error                   !Disk Recovery
  1071.   ALERT 2," | Disk Error Encountered | "+ERR$(ERR),1," OK ",a&
  1072.   RESUME err_return
  1073. err_return:
  1074.   CLOSE #1
  1075.   KILL "iomap.map"
  1076.   DEFMOUSE 0
  1077.   ALERT 1," | State Of Map Is Unknown. | Reload Recommended. |",1,"OK",a&
  1078.   GOSUB recover_screen
  1079. RETURN
  1080. > PROCEDURE ins_column_row                !Insert a column or row
  1081.   ALERT 2," |        Insert What?        | ",3," Column | Row | Cancel ",a&
  1082.   SELECT a&
  1083.   CASE 1
  1084.     overwrite&=FALSE
  1085.     FOR i&=0 TO ymax&
  1086.       IF map&(xmax&,i&)>=0
  1087.         overwrite&=TRUE
  1088.       ENDIF
  1089.     NEXT i&
  1090.     IF overwrite&
  1091.       ALERT 3," | WARNING: You Will | Lose The Eastern- | Most Column ",2," OK | Cancel ",a&
  1092.       IF a&=1
  1093.         overwrite&=FALSE
  1094.       ENDIF
  1095.     ENDIF
  1096.     IF overwrite&=FALSE
  1097.       GOSUB select_map_loc
  1098.       DEFMOUSE 2
  1099.       FOR i&=xmax& TO 0 STEP -1
  1100.         FOR j&=ymax& TO x&+1+xbase& STEP -1
  1101.           map&(j&,i&)=map&(j&-1,i&)
  1102.         NEXT j&
  1103.         map&(j&,i&)=-1
  1104.       NEXT i&
  1105.       GOSUB redraw_from_array
  1106.       map_saved&=FALSE
  1107.       DEFMOUSE 0
  1108.       map_saved&=FALSE
  1109.     ENDIF
  1110.   CASE 2
  1111.     overwrite&=FALSE
  1112.     FOR i&=0 TO xmax&
  1113.       IF map&(i&,ymax&)>=0
  1114.         overwrite&=TRUE
  1115.       ENDIF
  1116.     NEXT i&
  1117.     IF overwrite&
  1118.       ALERT 1," | WARNING: You Will | Lose The Southern- | Most Row ",2," OK | Cancel ",a&
  1119.       IF a&=1
  1120.         overwrite&=FALSE
  1121.       ENDIF
  1122.     ENDIF
  1123.     IF overwrite&=FALSE
  1124.       GOSUB select_map_loc
  1125.       DEFMOUSE 2
  1126.       FOR i&=ymax& TO 0 STEP -1
  1127.         FOR j&=xmax& TO y&+1+ybase& STEP -1
  1128.           map&(i&,j&)=map&(i&,j&-1)
  1129.         NEXT j&
  1130.         map&(i&,j&)=-1
  1131.       NEXT i&
  1132.       GOSUB redraw_from_array
  1133.       DEFMOUSE 0
  1134.       map_saved&=FALSE
  1135.     ENDIF
  1136.   ENDSELECT
  1137. RETURN
  1138. > PROCEDURE del_column_row                !Delete a column or row
  1139.   ALERT 2," |        Delete What?        | ",3," Column | Row | Cancel ",a&
  1140.   SELECT a&
  1141.   CASE 1
  1142.     GOSUB select_map_loc
  1143.     DEFMOUSE 2
  1144.     FOR i&=0 TO xmax&
  1145.       FOR j&=x&+xbase& TO ymax&-1
  1146.         map&(j&,i&)=map&(j&+1,i&)
  1147.       NEXT j&
  1148.       map&(ymax&,i&)=-1
  1149.     NEXT i&
  1150.     GOSUB redraw_from_array
  1151.     map_saved&=FALSE
  1152.     DEFMOUSE 0
  1153.   CASE 2
  1154.     GOSUB select_map_loc
  1155.     DEFMOUSE 2
  1156.     FOR i&=0 TO ymax&
  1157.       FOR j&=y&+ybase& TO xmax&-1
  1158.         map&(i&,j&)=map&(i&,j&+1)
  1159.       NEXT j&
  1160.       map&(i&,xmax&)=-1
  1161.     NEXT i&
  1162.     GOSUB redraw_from_array
  1163.     map_saved&=FALSE
  1164.     DEFMOUSE 0
  1165.   ENDSELECT
  1166. RETURN
  1167. > PROCEDURE fill_area                     !Fill all similiar connecting spaces
  1168.   ARRAYFILL m|(),0
  1169.   cursor2$=cursor$
  1170.   cursor2&=cursor&
  1171.   ALERT 2," | Select An Icon To Fill       | With. | Right Click When Done. | ",1," OK | Cursor | Cancel ",a&
  1172.   IF a&<3
  1173.     IF a&=1
  1174.       MOUSE mx&,my&,mse&
  1175.       WHILE mse&<>2
  1176.         MOUSE mx&,my&,mse&
  1177.         GOSUB icon_main_loop
  1178.       WEND
  1179.     ENDIF
  1180.     GOSUB select_map_loc
  1181.     DEFMOUSE 2
  1182.     loc&=map&(x&+xbase&,y&+ybase&)
  1183.     m|(x&,y&)=2                       !0=no,1=yes,2=check
  1184.     no_more&=FALSE
  1185.     REPEAT
  1186.       no_more&=TRUE
  1187.       FOR i&=0 TO 31
  1188.         FOR j&=0 TO 19
  1189.           IF m|(i&,j&)=2
  1190.             IF map&(i&+xbase&,j&+ybase&)=loc&
  1191.               map&(i&+xbase&,j&+ybase&)=cursor&
  1192.               m|(i&,j&)=1
  1193.             ELSE
  1194.               m|(i&,j&)=0
  1195.             ENDIF
  1196.             no_more&=FALSE
  1197.             ' ** y-1
  1198.             IF j&>0
  1199.               IF map&(i&+xbase&,j&+ybase&-1)=loc&
  1200.                 IF m|(i&,j&-1)<>1
  1201.                   m|(i&,j&-1)=2
  1202.                 ENDIF
  1203.               ENDIF
  1204.             ENDIF
  1205.             ' ** y+1
  1206.             IF j&+ybase&<ymax&
  1207.               IF map&(i&+xbase&,j&+ybase&+1)=loc&
  1208.                 IF m|(i&,j&+1)<>1
  1209.                   m|(i&,j&+1)=2
  1210.                 ENDIF
  1211.               ENDIF
  1212.             ENDIF
  1213.             ' ** x-1
  1214.             IF i&>0
  1215.               IF map&(i&+xbase&-1,j&+ybase&)=loc&
  1216.                 IF m|(i&-1,j&)<>1
  1217.                   m|(i&-1,j&)=2
  1218.                 ENDIF
  1219.               ENDIF
  1220.               ' ** x+1
  1221.             ENDIF
  1222.             IF i&+xbase&<xmax&
  1223.               IF map&(i&+xbase&+1,j&+ybase&)=loc&
  1224.                 IF m|(i&+1,j&)<>1
  1225.                   m|(i&+1,j&)=2
  1226.                 ENDIF
  1227.               ENDIF
  1228.             ENDIF
  1229.           ENDIF
  1230.         NEXT j&
  1231.       NEXT i&
  1232.     UNTIL no_more&
  1233.     map_saved&=FALSE
  1234.     GOSUB redraw_from_array
  1235.     DEFMOUSE 0
  1236.   ENDIF
  1237.   cursor$=cursor2$
  1238.   cursor&=cursor2&
  1239.   DEFMOUSE 0
  1240. RETURN
  1241. > PROCEDURE print_graph_paper             !Utility to print graph paper <EPSON>
  1242.   ' THIS IS TESTED ON AN EPSON LX-86 ONLY.
  1243.   '
  1244.   FOR loop&=0 TO 1
  1245.     ~FORM_DIAL(loop&,0,0,0,0,x7%,y7%,w7%,h7%)
  1246.   NEXT loop&
  1247.   ~OBJC_CHANGE(dialog7%,14,0,x7%,y7%,w7%,h7%,32,0)
  1248.   ~OBJC_DRAW(dialog7%,0,2,x7%,y7%,w7%,h7%)
  1249.   obj7%=FORM_DO(dialog7%,0)
  1250.   ~OBJC_CHANGE(dialog7%,obj7%,0,x7%,y7%,w7%,h7%,0,0)
  1251.   IF BTST(OB_STATE(dialog7%,13),0)               !Line joins?
  1252.     joins|=128                                   !Yes
  1253.   ELSE
  1254.     joins|=32                                    !No
  1255.   ENDIF
  1256.   IF obj7%=14
  1257.     DEFMOUSE 2
  1258.     size&=VAL(CHAR{{OB_SPEC(dialog7%,7)}})       !Size
  1259.     IF size&=0                                   !Zero not allowed
  1260.       size&=1
  1261.     ENDIF
  1262.     LPRINT CHR$(27)+"1";                         !No pixels between rows
  1263.     LPRINT CHR$(27)+"m"+CHR$(4)                  !Graphics character set
  1264.     y&=INT(79/(size&+1))
  1265.     z&=INT(107/(size&+1))
  1266.     FOR i&=1 TO VAL(CHAR{{OB_SPEC(dialog7%,4)}})          ! Quantity
  1267.       IF i&>1
  1268.         LPRINT CHR$(12)
  1269.       ENDIF
  1270.       FOR j&=1 TO z&
  1271.         FOR k&=1 TO y&
  1272.           LPRINT CHR$(joins|);
  1273.           FOR l&=1 TO size&
  1274.             LPRINT CHR$(133);
  1275.           NEXT l&
  1276.         NEXT k&
  1277.         LPRINT CHR$(joins|)
  1278.         FOR k&=1 TO size&
  1279.           FOR l&=1 TO y&
  1280.             LPRINT CHR$(134);
  1281.             FOR m&=1 TO size&
  1282.               LPRINT CHR$(32);
  1283.             NEXT m&
  1284.           NEXT l&
  1285.           LPRINT CHR$(134)
  1286.         NEXT k&
  1287.       NEXT j&
  1288.       FOR j&=1 TO y&
  1289.         LPRINT CHR$(joins|);
  1290.         FOR k&=1 TO size&
  1291.           LPRINT CHR$(133);
  1292.         NEXT k&
  1293.       NEXT j&
  1294.       LPRINT CHR$(joins|)
  1295.     NEXT i&
  1296.     LPRINT CHR$(12)                       !Eject Page
  1297.     DEFMOUSE 0
  1298.   ENDIF
  1299.   FOR loop&=2 TO 3
  1300.     ~FORM_DIAL(loop&,0,0,0,0,x7%,y7%,w7%,h7%)
  1301.   NEXT loop&
  1302.   GOSUB recover_screen
  1303. RETURN
  1304. > PROCEDURE quit                          !Clean up memory and that's all folks!
  1305.   ~RSRC_FREE()
  1306.   RESERVE FRE(0)+33000
  1307.   forever&=FALSE
  1308. RETURN
  1309. > PROCEDURE allocate_screens              !Initialize page flip
  1310.   ' *************************************************************************
  1311.   ' THIS CODE ISN'T MINE - JC
  1312.   ' (I wish I knew who to thank for it - it came off some sample code
  1313.   ' that I downloaded somewhere...)
  1314.   ' I'm not really using page flipping in this program.  I read the icons
  1315.   ' at logical base while drawing the map at physical base...  It's more
  1316.   ' like dual-screen processing...?
  1317.   ' The below comments came with the code, though I've chopped things up to
  1318.   ' take out the actual page flip.
  1319.   ' *************************************************************************
  1320.   ' Save original screen settings:
  1321.   '
  1322.   physbase%=XBIOS(2)
  1323.   logbase%=XBIOS(3)
  1324.   '
  1325.   DIM screen$(2),screen%(2)
  1326.   '
  1327.   ' Set up two screens in memory.  More are just as easy.  Each needs to be
  1328.   ' on a 512 byte boundry, so dimension a string to 32512 bytes and then
  1329.   ' move to the boundry.
  1330.   '
  1331.   screen%(1)=physbase%
  1332.   screen$(2)=SPACE$(32512)
  1333.   screen%(2)=(INT(VARPTR(screen$(2))/512)+1)*512
  1334. RETURN
  1335. > PROCEDURE config_printer                !1280 or 960 pixels/print to screen?
  1336.   r%=XBIOS(33,-1)
  1337.   IF BTST(r%,2)
  1338.     ~OBJC_CHANGE(dialog6%,6,0,x6%,y6%,w6%,h6%,0,0)
  1339.     ~OBJC_CHANGE(dialog6%,5,0,x6%,y6%,w6%,h6%,1,0)
  1340.   ELSE
  1341.     ~OBJC_CHANGE(dialog6%,6,0,x6%,y6%,w6%,h6%,1,0)
  1342.     ~OBJC_CHANGE(dialog6%,5,0,x6%,y6%,w6%,h6%,0,0)
  1343.   ENDIF
  1344.   IF print_to_screen&
  1345.     ~OBJC_CHANGE(dialog6%,9,0,x6%,y6%,w6%,h6%,1,0)
  1346.     ~OBJC_CHANGE(dialog6%,10,0,x6%,y6%,w6%,h6%,0,0)
  1347.   ELSE
  1348.     ~OBJC_CHANGE(dialog6%,9,0,x6%,y6%,w6%,h6%,0,0)
  1349.     ~OBJC_CHANGE(dialog6%,10,0,x6%,y6%,w6%,h6%,1,0)
  1350.   ENDIF
  1351.   FOR loop&=0 TO 1
  1352.     ~FORM_DIAL(loop&,0,0,0,0,x6%,y6%,w6%,h6%)
  1353.   NEXT loop&
  1354.   ~OBJC_CHANGE(dialog6%,12,0,x6%,y6%,w6%,h6%,32,0)
  1355.   ~OBJC_DRAW(dialog6%,0,2,x6%,y6%,w6%,h6%)
  1356.   obj6%=FORM_DO(dialog6%,0)
  1357.   IF BTST(OB_STATE(dialog6%,6),0)
  1358.     ~XBIOS(33,BCLR(r%,2))                     !Atari
  1359.   ELSE
  1360.     ~XBIOS(33,BSET(r%,2))                     !Epson
  1361.   ENDIF
  1362.   IF BTST(OB_STATE(dialog6%,10),0)
  1363.     print_to_screen&=FALSE                    !Printer
  1364.   ELSE
  1365.     print_to_screen&=TRUE                     !Screen
  1366.   ENDIF
  1367.   FOR loop&=2 TO 3
  1368.     ~FORM_DIAL(loop&,0,0,0,0,x6%,y6%,w6%,h6%)
  1369.   NEXT loop&
  1370. RETURN
  1371. > PROCEDURE print_tiled                   !Pages join together to form 1 map
  1372.   IF print_to_screen&
  1373.     ALERT 3," PRINT TILED TO SCREEN: | | Confirm Choice.",1," OK | Cancel ",a&
  1374.   ELSE
  1375.     ALERT 3," PRINT TILED TO PRINTER: | | Align Paper And | Set Top Of Form.",1," OK | Cancel ",a&
  1376.   ENDIF
  1377.   IF a&=1
  1378.     ' A screen is 40X25
  1379.     '  DIM pr&(25,6)                 !6=lo-x,lo-y,,n,e,s,w
  1380.     prx&=18
  1381.     pry&=31
  1382.     prpnt|=0
  1383.     prxbase&=0
  1384.     WHILE prxbase&<xmax&                  !Decide what (x,y) coordinates
  1385.       prybase&=0                          !each screen should start on...
  1386.       WHILE prybase&<ymax&
  1387.         pr&(prpnt|,1)=prxbase&
  1388.         pr&(prpnt|,2)=prybase&
  1389.         IF prybase&+pry&>ymax&
  1390.           prybase&=ymax&
  1391.         ELSE
  1392.           prybase&=prybase&+pry&+1
  1393.         ENDIF
  1394.         INC prpnt|
  1395.       WEND
  1396.       IF prxbase&+prx&>xmax&
  1397.         prxbase&=xmax&
  1398.       ELSE
  1399.         prxbase&=prxbase&+prx&+1
  1400.       ENDIF
  1401.     WEND
  1402.     DEC prpnt|
  1403.     x&=pr&(0,1)                           !Determine map count (x,y)
  1404.     ycnt&=0
  1405.     i&=0
  1406.     WHILE pr&(i&,1)=x&
  1407.       INC i&
  1408.       INC ycnt&
  1409.     WEND
  1410.     xcnt&=prpnt|/ycnt&
  1411.     IF MOD(prpnt|,ycnt&)>0
  1412.       INC xcnt&
  1413.     ENDIF
  1414.     FOR i&=0 TO prpnt|                    !Fill touching east
  1415.       IF pr&(i&+1,2)>pr&(i&,2)
  1416.         pr&(i&,4)=i&+1
  1417.       ELSE
  1418.         pr&(i&,4)=-1
  1419.       ENDIF
  1420.     NEXT i&
  1421.     FOR i&=prpnt| TO 1 STEP -1            !Fill touching west
  1422.       IF pr&(i&-1,2)<pr&(i&,2)
  1423.         pr&(i&,6)=i&-1
  1424.       ELSE
  1425.         pr&(i&,6)=-1
  1426.       ENDIF
  1427.     NEXT i&
  1428.     FOR i&=0 TO prpnt|                    !Fill touching south
  1429.       IF i&+ycnt&<=prpnt|
  1430.         pr&(i&,5)=i&+ycnt&
  1431.       ELSE
  1432.         pr&(i&,5)=-1
  1433.       ENDIF
  1434.     NEXT i&
  1435.     FOR i&=prpnt| TO 1 STEP -1            !Fill touching north
  1436.       IF i&-ycnt&>=0
  1437.         pr&(i&,3)=i&-ycnt&
  1438.       ELSE
  1439.         pr&(i&,3)=-1
  1440.       ENDIF
  1441.     NEXT i&
  1442.     ARRAYFILL l&(),-1                           !Legend internal
  1443.     '  DIM pr&(25,6)                 !6=lo-x,lo-y,,n,e,s,w
  1444.     on_page&=0                                  !Legend pointer
  1445.     FOR i|=0 TO prpnt|
  1446.       CLS
  1447.       IF pr&(i|,3)=-1 AND pr&(i|,6)=-1          !Upper left map tile?
  1448.         PRINT AT(1,1);title$;
  1449.       ENDIF
  1450.       IF pr&(i|,3)=-1 AND pr&(i|,4)=-1          !Upper right map tile?
  1451.         PRINT AT(41-LEN(subtitle$),1);subtitle$;
  1452.       ENDIF
  1453.       IF pr&(i|,3)=-1                           !Upper edge of map?
  1454.         DEFLINE ,1,2,2
  1455.         LINE 0,8,319,8
  1456.       ENDIF
  1457.       IF pr&(i|,2)+pry&>ymax&
  1458.         y&=ymax&-pr&(i|,2)
  1459.       ELSE
  1460.         y&=pry&
  1461.       ENDIF
  1462.       is&=0
  1463.       FOR i&=pr&(i|,2) TO pr&(i|,2)+y&
  1464.         IF pr&(i|,1)+prx&>xmax&
  1465.           z&=xmax&-pr&(i|,1)
  1466.         ELSE
  1467.           z&=prx&
  1468.         ENDIF
  1469.         js&=0
  1470.         FOR j&=pr&(i|,1) TO pr&(i|,1)+z&
  1471.           cursory&=INT(map&(i&,j&)/32)*10
  1472.           cursorx&=MOD(map&(i&,j&),32)*10
  1473.           cursor2&=map&(i&,j&)
  1474.           IF l_current_max&>0
  1475.             FOR k&=0 TO l_current_max&-1            !Should this icon be in the
  1476.               IF legend&(k&)=cursor2&               !legend?
  1477.                 already&=FALSE
  1478.                 FOR a&=0 TO on_page&                !Is it already identified?
  1479.                   IF l&(a&)=k&
  1480.                     already&=TRUE
  1481.                   ENDIF
  1482.                 NEXT a&
  1483.                 IF NOT already&                     !No, add it to legend.
  1484.                   l&(on_page&)=k&                   !Store POINTER into legend&
  1485.                   INC on_page&
  1486.                 ENDIF
  1487.               ENDIF
  1488.             NEXT k&
  1489.           ENDIF
  1490.           ~XBIOS(5,L:screen%(2),L:screen%(1),-1)  !Peek at the icon screen
  1491.           GET cursorx&,cursory&,cursorx&+9,cursory&+9,cursor2$  !Get an icon
  1492.           ~XBIOS(5,L:screen%(1),L:screen%(1),-1)  !Back to the map
  1493.           IF pr&(i|,3)=-1                         !If upper edge of map
  1494.             PUT is&*10,js&*10+10,cursor2$         !Leave room for the goodies
  1495.           ELSE
  1496.             PUT is&*10,js&*10+10,cursor2$            !Otherwise just drop it
  1497.           ENDIF
  1498.           INC js&
  1499.         NEXT j&
  1500.         INC is&
  1501.       NEXT i&
  1502.       GOSUB print_screen
  1503.       GOSUB page_eject
  1504.     NEXT i|
  1505.     lin_width|=8
  1506.     h_count&=0
  1507.     IF on_page&>0
  1508.       CLS
  1509.       x$=" L E G E N D "
  1510.       x&=(319/2)-(LEN(x$)*8/2)
  1511.       DEFTEXT ,0,0,6
  1512.       TEXT x&,15,x$
  1513.       LINE 0,7,319,7
  1514.       LINE 0,17,319,17
  1515.       lin_count&=3
  1516.       h_count&=0
  1517.       left_side&=0
  1518.       advancel&=0
  1519.       advancer&=0
  1520.       FOR i&=0 TO on_page&-1
  1521.         cursory&=INT(legend&(l&(i&))/32)*10
  1522.         cursorx&=MOD(legend&(l&(i&)),32)*10
  1523.         ~XBIOS(5,L:screen%(2),L:screen%(1),-1)  !Peek at the icon screen
  1524.         GET cursorx&,cursory&,cursorx&+9,cursory&+9,cursor2$  !Get an icon
  1525.         ~XBIOS(5,L:screen%(1),L:screen%(1),-1)  !Back to the map
  1526.         PUT 1+left_side&,(lin_count&-1)*lin_width|+3,cursor2$
  1527.         k&=0
  1528.         FOR j&=0 TO 4
  1529.           IF legend$(l&(i&),j&)>""
  1530.             DEFTEXT ,0,0,4
  1531.             IF k&<2
  1532.               TEXT 14+left_side&,(lin_count&)*lin_width|,legend$(l&(i&),j&)
  1533.               INC k&
  1534.             ELSE
  1535.               TEXT 2+left_side&,(lin_count&)*lin_width|,legend$(l&(i&),j&)
  1536.             ENDIF
  1537.             IF left_side&=0
  1538.               INC advancel&
  1539.             ELSE
  1540.               INC advancer&
  1541.             ENDIF
  1542.             INC lin_count&
  1543.           ENDIF
  1544.           IF h_count&>0 AND (lin_count&>=23 OR (lin_count&>=22 AND j&=4))
  1545.             GOSUB bottom_entry
  1546.             GOSUB print_screen
  1547.             GOSUB page_eject
  1548.             CLS
  1549.             x$=" L E G E N D (Con't)"
  1550.             x&=(319/2)-(LEN(x$)*8/2)
  1551.             DEFTEXT ,0,0,6
  1552.             TEXT x&,15,x$
  1553.             LINE 0,7,319,7
  1554.             LINE 0,17,319,17
  1555.             lin_count&=3
  1556.             GOSUB top_entry
  1557.             h_count&=0
  1558.             left_side&=1
  1559.             advancel&=0
  1560.             advancer&=0
  1561.           ENDIF
  1562.           IF h_count&=0 AND (lin_count&>=25 OR (lin_count&>=24 AND j&=4))
  1563.             GOSUB bottom_entry
  1564.             GOSUB print_screen
  1565.             CLS
  1566.             lin_count&=1
  1567.             GOSUB top_entry
  1568.             INC h_count&
  1569.             left_side&=1
  1570.             advancel&=0
  1571.             advancer&=0
  1572.           ENDIF
  1573.         NEXT j&
  1574.         INC lin_count&
  1575.         IF left_side&=0
  1576.           left_side&=21*8
  1577.           lin_count&=lin_count&-advancel&-1
  1578.         ELSE
  1579.           left_side&=0
  1580.           IF advancer&<advancel&
  1581.             lin_count&=lin_count&+advancel&-advancer&
  1582.           ENDIF
  1583.           advancel&=0
  1584.           advancer&=0
  1585.         ENDIF
  1586.       NEXT i&
  1587.       GOSUB print_screen
  1588.     ENDIF
  1589.     GOSUB page_eject
  1590.     GOSUB redraw_from_array
  1591.   ENDIF
  1592. RETURN
  1593. > PROCEDURE print_paged                   !Notebook style with page # references
  1594.   IF print_to_screen&
  1595.     ALERT 3," PRINT PAGED TO SCREEN: | | Confirm Choice.",1," OK | Cancel ",a&
  1596.   ELSE
  1597.     ALERT 3," PRINT PAGED TO PRINTER: | | Align Paper And | Set Top Of Form.",1," OK | Cancel ",a&
  1598.   ENDIF
  1599.   IF a&=1
  1600.     ' A screen is 40X25
  1601.     '  DIM pr&(25,6)                 !6=lo-x,lo-y,,n,e,s,w
  1602.     prx&=16
  1603.     pry&=29
  1604.     prpnt|=0
  1605.     prxbase&=0
  1606.     WHILE prxbase&<xmax&                  !Decide what (x,y) coordinates
  1607.       prybase&=0                          !each screen should start on...
  1608.       WHILE prybase&<ymax&
  1609.         pr&(prpnt|,1)=prxbase&
  1610.         pr&(prpnt|,2)=prybase&
  1611.         IF prybase&+pry&>ymax&
  1612.           prybase&=ymax&
  1613.         ELSE
  1614.           prybase&=prybase&+pry&+1
  1615.         ENDIF
  1616.         INC prpnt|
  1617.       WEND
  1618.       IF prxbase&+prx&>xmax&
  1619.         prxbase&=xmax&
  1620.       ELSE
  1621.         prxbase&=prxbase&+prx&+1
  1622.       ENDIF
  1623.     WEND
  1624.     DEC prpnt|
  1625.     x&=pr&(0,1)                           !Determine map count (x,y)
  1626.     ycnt&=0
  1627.     i&=0
  1628.     WHILE pr&(i&,1)=x&
  1629.       INC i&
  1630.       INC ycnt&
  1631.     WEND
  1632.     xcnt&=prpnt|/ycnt&
  1633.     IF MOD(prpnt|,ycnt&)>0
  1634.       INC xcnt&
  1635.     ENDIF
  1636.     FOR i&=0 TO prpnt|                    !Fill touching east
  1637.       IF pr&(i&+1,2)>pr&(i&,2)
  1638.         pr&(i&,4)=i&+1
  1639.       ELSE
  1640.         pr&(i&,4)=-1
  1641.       ENDIF
  1642.     NEXT i&
  1643.     FOR i&=prpnt| TO 1 STEP -1            !Fill touching west
  1644.       IF pr&(i&-1,2)<pr&(i&,2)
  1645.         pr&(i&,6)=i&-1
  1646.       ELSE
  1647.         pr&(i&,6)=-1
  1648.       ENDIF
  1649.     NEXT i&
  1650.     FOR i&=0 TO prpnt|                    !Fill touching south
  1651.       IF i&+ycnt&<=prpnt|
  1652.         pr&(i&,5)=i&+ycnt&
  1653.       ELSE
  1654.         pr&(i&,5)=-1
  1655.       ENDIF
  1656.     NEXT i&
  1657.     FOR i&=prpnt| TO 1 STEP -1            !Fill touching north
  1658.       IF i&-ycnt&>=0
  1659.         pr&(i&,3)=i&-ycnt&
  1660.       ELSE
  1661.         pr&(i&,3)=-1
  1662.       ENDIF
  1663.     NEXT i&
  1664.     FOR i|=0 TO prpnt|
  1665.       on_page&=0                                  !Legend pointer
  1666.       ARRAYFILL l&(),-1                           !Legend internal
  1667.       CLS
  1668.       PRINT AT(1,1);title$;
  1669.       PRINT AT(41-LEN(subtitle$),1);subtitle$;
  1670.       x$=" PAGE "+STR$(i|+1)+" "
  1671.       DEFLINE ,1,2,2
  1672.       LINE 0,8,319,8
  1673.       x&=(319/2)-(LEN(x$)*8/2)
  1674.       DEFTEXT ,0,0,6
  1675.       TEXT x&,6,x$
  1676.       IF pr&(i|,6)=-1                             !Route West
  1677.         x$="End Of Map West"
  1678.       ELSE
  1679.         x$="West To Page "+STR$(pr&(i|,6)+1)
  1680.       ENDIF
  1681.       x&=(LEN(x$)*8/2)+(199/2)
  1682.       DEFTEXT ,0,900,6
  1683.       TEXT 6,x&,x$
  1684.       IF pr&(i|,4)=-1                             !Route East
  1685.         x$="End Of Map East"
  1686.       ELSE
  1687.         x$="East To Page "+STR$(pr&(i|,4)+1)
  1688.       ENDIF
  1689.       x&=(199/2)-(LEN(x$)*8/2)
  1690.       DEFTEXT ,0,2700,6
  1691.       TEXT 313,x&,x$
  1692.       IF pr&(i|,3)=-1                             !Route North
  1693.         x$="End Of Map North"
  1694.       ELSE
  1695.         x$="North To Page "+STR$(pr&(i|,3)+1)
  1696.       ENDIF
  1697.       x&=(319/2)-(LEN(x$)*8/2)
  1698.       DEFTEXT ,0,0,6
  1699.       TEXT x&,16,x$
  1700.       IF pr&(i|,5)=-1                             !Route South
  1701.         x$="End Of Map South"
  1702.       ELSE
  1703.         x$="South To Page "+STR$(pr&(i|,5)+1)
  1704.       ENDIF
  1705.       x&=(319/2)-(LEN(x$)*8/2)
  1706.       DEFTEXT ,0,0,6
  1707.       TEXT x&,198,x$
  1708.       IF pr&(i|,2)+pry&>ymax&
  1709.         y&=ymax&-pr&(i|,2)
  1710.       ELSE
  1711.         y&=pry&
  1712.       ENDIF
  1713.       is&=0
  1714.       FOR i&=pr&(i|,2) TO pr&(i|,2)+y&
  1715.         IF pr&(i|,1)+prx&>xmax&
  1716.           z&=xmax&-pr&(i|,1)
  1717.         ELSE
  1718.           z&=prx&
  1719.         ENDIF
  1720.         js&=0
  1721.         FOR j&=pr&(i|,1) TO pr&(i|,1)+z&
  1722.           cursory&=INT(map&(i&,j&)/32)*10
  1723.           cursorx&=MOD(map&(i&,j&),32)*10
  1724.           cursor2&=map&(i&,j&)
  1725.           IF l_current_max&>0
  1726.             FOR k&=0 TO l_current_max&-1            !Should this icon be in this
  1727.               IF legend&(k&)=cursor2&               !page's legend?
  1728.                 already&=FALSE
  1729.                 FOR a&=0 TO on_page&                !Is it already identified?
  1730.                   IF l&(a&)=k&
  1731.                     already&=TRUE
  1732.                   ENDIF
  1733.                 NEXT a&
  1734.                 IF NOT already&                     !No, add it to legend.
  1735.                   l&(on_page&)=k&                   !Store POINTER to legend&
  1736.                   INC on_page&
  1737.                 ENDIF
  1738.               ENDIF
  1739.             NEXT k&
  1740.           ENDIF
  1741.           ~XBIOS(5,L:screen%(2),L:screen%(1),-1)  !Peek at the icon screen
  1742.           GET cursorx&,cursory&,cursorx&+9,cursory&+9,cursor2$  !Get an icon
  1743.           ~XBIOS(5,L:screen%(1),L:screen%(1),-1)  !Back to the map
  1744.           PUT is&*10+10,js&*10+20,cursor2$
  1745.           INC js&
  1746.         NEXT j&
  1747.         INC is&
  1748.       NEXT i&
  1749.       GOSUB print_screen
  1750.       CLS
  1751.       lin_width|=8
  1752.       h_count&=0
  1753.       IF on_page&>0
  1754.         CLS
  1755.         x$=" L E G E N D "
  1756.         x&=(319/2)-(LEN(x$)*8/2)
  1757.         DEFTEXT ,0,0,6
  1758.         TEXT x&,15,x$
  1759.         LINE 0,7,319,7
  1760.         LINE 0,17,319,17
  1761.         lin_count&=3
  1762.         page_no&=0
  1763.         left_side&=0
  1764.         advancel&=0
  1765.         advancer&=0
  1766.         FOR i&=0 TO on_page&-1
  1767.           cursory&=INT(legend&(l&(i&))/32)*10
  1768.           cursorx&=MOD(legend&(l&(i&)),32)*10
  1769.           ~XBIOS(5,L:screen%(2),L:screen%(1),-1)  !Peek at the icon screen
  1770.           GET cursorx&,cursory&,cursorx&+9,cursory&+9,cursor2$  !Get an icon
  1771.           ~XBIOS(5,L:screen%(1),L:screen%(1),-1)  !Back to the map
  1772.           PUT 1+left_side&,(lin_count&-1)*lin_width|+3,cursor2$
  1773.           k&=0
  1774.           FOR j&=0 TO 4
  1775.             IF legend$(l&(i&),j&)>""
  1776.               DEFTEXT ,0,0,4
  1777.               IF k&<2
  1778.                 TEXT 14+left_side&,(lin_count&)*lin_width|,legend$(l&(i&),j&)
  1779.                 INC k&
  1780.               ELSE
  1781.                 TEXT 2+left_side&,(lin_count&)*lin_width|,legend$(l&(i&),j&)
  1782.               ENDIF
  1783.               IF left_side&=0
  1784.                 INC advancel&
  1785.               ELSE
  1786.                 INC advancer&
  1787.               ENDIF
  1788.               INC lin_count&
  1789.             ENDIF
  1790.             IF page_no&=0 AND (lin_count&>=23 OR (lin_count&>=22 AND j&=4))
  1791.               GOSUB bottom_entry
  1792.               GOSUB print_screen
  1793.               GOSUB page_eject
  1794.               CLS
  1795.               x$=" L E G E N D (Con't)"
  1796.               x&=(319/2)-(LEN(x$)*8/2)
  1797.               DEFTEXT ,0,0,6
  1798.               TEXT x&,15,x$
  1799.               LINE 0,7,319,7
  1800.               LINE 0,17,319,17
  1801.               lin_count&=3
  1802.               GOSUB top_entry
  1803.               INC page_no&
  1804.               h_count&=0
  1805.               left_side&=1
  1806.               advancel&=0
  1807.               advancer&=0
  1808.             ENDIF
  1809.             IF page_no&>0 AND h_count&>0 AND (lin_count&>=22 OR (lin_count&>=21 AND j&=4))
  1810.               GOSUB bottom_entry
  1811.               GOSUB print_screen
  1812.               GOSUB page_eject
  1813.               CLS
  1814.               x$=" L E G E N D (Con't)"
  1815.               x&=(319/2)-(LEN(x$)*8/2)
  1816.               DEFTEXT ,0,0,6
  1817.               TEXT x&,15,x$
  1818.               LINE 0,7,319,7
  1819.               LINE 0,17,319,17
  1820.               lin_count&=3
  1821.               GOSUB top_entry
  1822.               INC page_no&
  1823.               h_count&=0
  1824.               left_side&=1
  1825.               advancel&=0
  1826.               advancer&=0
  1827.             ENDIF
  1828.             IF page_no&>0 AND h_count&=0 AND (lin_count&>=24 OR (lin_count&>=23 AND j&=4))
  1829.               GOSUB bottom_entry
  1830.               GOSUB print_screen
  1831.               CLS
  1832.               lin_count&=0
  1833.               GOSUB top_entry
  1834.               INC page_no&
  1835.               INC h_count&
  1836.               left_side&=1
  1837.               advancel&=0
  1838.               advancer&=0
  1839.             ENDIF
  1840.           NEXT j&
  1841.           INC lin_count&
  1842.           IF left_side&=0
  1843.             left_side&=21*8
  1844.             lin_count&=lin_count&-advancel&-1
  1845.           ELSE
  1846.             left_side&=0
  1847.             IF advancer&<advancel&
  1848.               lin_count&=lin_count&+advancel&-advancer&
  1849.             ENDIF
  1850.             advancel&=0
  1851.             advancer&=0
  1852.           ENDIF
  1853.         NEXT i&
  1854.         GOSUB print_screen
  1855.       ENDIF
  1856.       GOSUB page_eject
  1857.     NEXT i|
  1858.     GOSUB redraw_from_array
  1859.   ENDIF
  1860. RETURN
  1861. > PROCEDURE bottom_entry                  !Handle printing end of page legend
  1862.   kbe&=0
  1863.   IF i&<=on_page&-2
  1864.     bottom_page&=TRUE
  1865.     left_side&=21*8
  1866.     cursory&=INT(legend&(l&(i&+1))/32)*10
  1867.     cursorx&=MOD(legend&(l&(i&+1)),32)*10
  1868.     ~XBIOS(5,L:screen%(2),L:screen%(1),-1)  !Peek at the icon screen
  1869.     GET cursorx&,cursory&,cursorx&+9,cursory&+9,cursor2$  !Get an icon
  1870.     ~XBIOS(5,L:screen%(1),L:screen%(1),-1)  !Back to the map
  1871.     PUT 1+left_side&,(lin_count&-advancel&-1)*lin_width|+3,cursor2$
  1872.     FOR ibe&=0 TO 4
  1873.       IF kbe&<advancel&
  1874.         IF legend$(l&(i&+1),ibe&)>""
  1875.           DEFTEXT ,0,0,4
  1876.           IF kbe&<2
  1877.             TEXT 14+left_side&,(lin_count&-advancel&+kbe&)*lin_width|,legend$(l&(i&+1),ibe&)
  1878.             INC kbe&
  1879.           ELSE
  1880.             TEXT 2+left_side&,(lin_count&-advancel&+kbe&)*lin_width|,legend$(l&(i&+1),ibe&)
  1881.             INC kbe&
  1882.           ENDIF
  1883.         ENDIF
  1884.       ENDIF
  1885.     NEXT ibe&
  1886.   ENDIF
  1887. RETURN
  1888. > PROCEDURE top_entry                     !Does the top of the next page
  1889.   IF kbe&>0 AND kbe&<5
  1890.     FOR ite&=kbe& TO 4
  1891.       IF legend$(l&(i&),ite&)>""
  1892.         DEFTEXT ,0,0,4
  1893.         IF ite&<2
  1894.           TEXT 14,(lin_count&)*lin_width|,legend$(l&(i&),ite&)
  1895.           INC lin_count&
  1896.           INC advancel&
  1897.         ELSE
  1898.           TEXT 2,(lin_count&)*lin_width|,legend$(l&(i&),ite&)
  1899.           INC lin_count&
  1900.           INC advancel&
  1901.         ENDIF
  1902.       ELSE
  1903.         IF legend$(l&(i&+1),ite&)>""
  1904.           INC lin_count&
  1905.           INC advancel&
  1906.         ENDIF
  1907.       ENDIF
  1908.       IF legend$(l&(i&+1),ite&)>""
  1909.         DEFTEXT ,0,0,4
  1910.         IF kbe&<2
  1911.           TEXT 14+left_side&,(lin_count&-advancel&+kbe&)*lin_width|,legend$(l&(i&+1),ite&)
  1912.           INC kbe&
  1913.         ELSE
  1914.           TEXT 2+left_side&,(lin_count&-advancel&+kbe&)*lin_width|,legend$(l&(i&+1),ite&)
  1915.           INC kbe&
  1916.         ENDIF
  1917.       ENDIF
  1918.     NEXT ite&
  1919.   ENDIF
  1920.   INC i&
  1921.   j&=4
  1922. RETURN
  1923. > PROCEDURE print_screen                  !Output to choosen destination
  1924.   IF print_to_screen&
  1925.     ALERT 1," | Screen Print Here. | Press Return Twice | To Continue |",1,"OK|Printer",a&
  1926.     IF a&=1
  1927.       WHILE INKEY$=""
  1928.       WEND
  1929.     ELSE
  1930.       HIDEM
  1931.       HARDCOPY
  1932.       SHOWM
  1933.     ENDIF
  1934.   ELSE
  1935.     HIDEM
  1936.     HARDCOPY
  1937.     SHOWM
  1938.   ENDIF
  1939. RETURN
  1940. > PROCEDURE page_eject                    !Pop one off
  1941.   IF print_to_screen&
  1942.     ALERT 1," | Page Eject Here. | ",1,"OK|Printer",a&
  1943.     IF a&=2
  1944.       LPRINT CHR$(12);
  1945.     ENDIF
  1946.   ELSE
  1947.     LPRINT CHR$(12);
  1948.   ENDIF
  1949. RETURN
  1950. > PROCEDURE blank_cursor                  !So I can recognize a blank cursor
  1951.   blank$=""
  1952.   RESTORE blank_cursor_data
  1953.   FOR i&=1 TO 86
  1954.     READ a&
  1955.     blank$=blank$+CHR$(a&)
  1956.   NEXT i&
  1957. blank_cursor_data:
  1958.   DATA 0,9,0,9,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1959.   DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1960.   DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1961.   DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1962.   DATA 0,0,0,53,0,48
  1963. RETURN
  1964. > PROCEDURE edit_icons                    !Go fix an icon
  1965.   WHILE MOUSEK>0
  1966.   WEND
  1967.   cursor2$=cursor$
  1968.   cursor2&=cursor&
  1969.   ALERT 2," | Select The Icon To Edit. | Right Click When Done. ",1," OK | Cancel ",a&
  1970.   IF a&=1
  1971.     IF NOT on_icon&
  1972.       CLS
  1973.       SPUT icons$
  1974.     ENDIF
  1975.     MOUSE mx&,my&,mse&
  1976.     k&=FALSE
  1977.     WHILE mse&<>2
  1978.       MOUSE mx&,my&,mse&
  1979.       IF mse&=1
  1980.         k&=TRUE
  1981.         x&=INT(mx&/10)*10                   !This is the cursor% decode logic
  1982.         y&=INT(my&/10)*10
  1983.         GET x&,y&,x&+9,y&+9,cursor$         !Pick up the cursor$
  1984.         PUT x&,y&,cursor$,10                !Invert it and put it back down.
  1985.         FOR i&=1 TO 1000                    !Pause a sec...
  1986.         NEXT i&
  1987.         PUT x&,y&,cursor$                   !...And put it back down right.
  1988.         cursor&=(x&/10)+(y&/10)*32          !Important variable!
  1989.         cursorx&=x&
  1990.         cursory&=y&
  1991.       ENDIF
  1992.     WEND
  1993.     IF k&=TRUE
  1994.       CLS
  1995.       PRINT AT(12,2);"Edit Icon ... "
  1996.       PRINT AT(11,4);"Right Click When Done."
  1997.       PUT 21*10,8,cursor$
  1998.       FOR i&=0 TO 50 STEP 5
  1999.         LINE 135,i&+75,185,i&+75
  2000.         LINE i&+135,75,i&+135,125
  2001.       NEXT i&
  2002.       FOR i&=0 TO 10
  2003.         FOR j&=0 TO 10
  2004.           a&=POINT(i&+21*10,j&+8)
  2005.           IF a&=1
  2006.             FOR k&=0 TO 5
  2007.               LINE (i&*5+135),(j&*5+75+k&),(i&*5+140),(j&*5+75+k&)
  2008.             NEXT k&
  2009.           ENDIF
  2010.         NEXT j&
  2011.       NEXT i&
  2012.       MOUSE mx&,my&,mse&
  2013.       WHILE mse&<>2
  2014.         MOUSE mx&,my&,mse&
  2015.         IF mse&=1 AND mx&>=135 AND mx&<=185 AND my&>=75 AND my&<=125
  2016.           WHILE MOUSEK=1
  2017.           WEND
  2018.           a&=POINT(mx&,my&)
  2019.           mx&=INT(mx&/5)*5
  2020.           my&=INT(my&/5)*5
  2021.           IF a&=0
  2022.             COLOR 1
  2023.           ELSE
  2024.             COLOR 0
  2025.           ENDIF
  2026.           FOR k&=1 TO 4
  2027.             LINE mx&+1,my&+k&,mx&+4,my&+k&
  2028.           NEXT k&
  2029.           PLOT (mx&/5)-27+(21*10),(my&/5)-15+8
  2030.           COLOR 1
  2031.         ENDIF
  2032.       WEND
  2033.       ALERT 2," |      Save The Results?      | ",1," DISK |Screen|Neither",a&
  2034.       IF a&=1 OR a&=2
  2035.         GET 21*10,8,21*10+9,8+9,cursor$
  2036.         ~XBIOS(5,L:screen%(2),L:screen%(1),-1)  !Peek at the icon screen
  2037.         CLS
  2038.         SPUT icons$
  2039.         PUT cursorx&,cursory&,cursor$           !Put the icon down
  2040.         SGET icons$
  2041.         ~XBIOS(5,L:screen%(1),L:screen%(1),-1)  !Back to the map
  2042.         IF cursor&=cursor2&
  2043.           cursor2$=cursor$
  2044.         ENDIF
  2045.         IF a&=1
  2046.           BSAVE "\DMICONS.DAT",VARPTR(icons$),32000
  2047.         ENDIF
  2048.       ENDIF
  2049.     ELSE
  2050.       ALERT 1," | No Icon Selected | ",1," OK ",a&
  2051.     ENDIF
  2052.     cursor$=cursor2$
  2053.     cursor&=cursor2&
  2054.     GOSUB redraw_from_array
  2055.     SGET map$
  2056.     GOSUB recover_screen
  2057.   ENDIF
  2058. RETURN
  2059.